package com.lxx.aop;

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.lxx.annotation.Db;
import com.lxx.enums.DbType;
import com.lxx.utils.DataSourceDirectorUtil;

/**
 * 目前还没有启用该功能<br/>
 * 
 * service layer的某个方法，如果要使用数据库r/w分离的功能，需要做如下事情：<br/>
 * 1、方法签名，使用@Transactional进行标注
 * 2、方法签名的第一个参数，必须是DbType type，后面可以跟多个其他参数
 * 3、在applicationContext-transaction.xml里<aop:aspectj-autoproxy/>后面添加如下一行：
 *     <bean id="rwDbPartitionAspect" class="com.dongao.common.interceptor.aop.ReadWriteDbRouterAspect" />
 *             
 * 
 * @author user
 *
 */
@Order(value = 0)
@Component
@Aspect
public final class DataSourceAspect {
	private static Log log = LogFactory.getLog(DataSourceAspect.class);	
		
	@Around("execution(* com.lxx.service.*.*(..))")
	public Object around(final ProceedingJoinPoint pjp) throws Throwable {	
		Object obj = null;
		try {
			Method m = ((MethodSignature)pjp.getSignature()).getMethod();
			Db ds =  m.getAnnotation(Db.class);
			if (ds != null) {
				DataSourceDirectorUtil.setActionDataSourceType();// 保留web层的数据源类型
				if (ds.type().equals(DbType.MASTER)) {
					DataSourceDirectorUtil.useMaster();
				} else if (ds.type().equals(DbType.SPHINX)) {
					DataSourceDirectorUtil.useSphinx();
				} else if (ds.type().equals(DbType.SLOW)) {
					DataSourceDirectorUtil.useSlow();
				} else if (ds.type().equals(DbType.LAWSPHINX)) {
					DataSourceDirectorUtil.useLawSphinx();
				} else if (ds.type().equals(DbType.LOGMASTER)) {
					DataSourceDirectorUtil.useLogMaster();
				} else if (ds.type().equals(DbType.LOGSLAVE)) {
					DataSourceDirectorUtil.useLogSlave();
				} else {
					DataSourceDirectorUtil.useSlave();
				}
			}
			
			obj = pjp.proceed(pjp.getArgs());
			
			if(ds != null){
				DataSourceDirectorUtil.backToActionSourceType();//继续使用web层配置的数据源
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return obj;
	}
}
